/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Lorena
 */
import InstrumentationPackage.*;
import EventPackage.*;

public class AlarmController {

    public static void main(String args[]) {
        String EvtMgrIP;					// Event Manager IP address
        Event Evt = null;					// Event object
        EventQueue eq = null;				// Message Queue
        int HBDeviceID = 110;                   //Unique ID for Alarm Controller
        int alarmEvent = 11;
        int armedEvent = 21;
        EventManagerInterface em = null;	// Interface object to the event manager
        boolean AlarmState = false;         //state of  alarm
        boolean ArmedState = true;         //state of whether system is armed or disarmed
        int Delay = 2500;					// The loop delay (2.5 seconds)
        boolean Done = false;				// Loop termination flag
        HeartBeat heartBeat = null;
        /////////////////////////////////////////////////////////////////////////////////
        // Get the IP address of the event manager
        /////////////////////////////////////////////////////////////////////////////////

        if (args.length == 0) {
            // event manager is on the local system

            System.out.println("\n\nAttempting to register on the local machine...");

            try {
                // Here we create an event manager interface object. This assumes
                // that the event manager is on the local machine
                heartBeat = new HeartBeat(HBDeviceID);
                em = new EventManagerInterface();
            } catch (Exception e) {
                System.out.println("Error instantiating event manager interface: " + e);

            } // catch

        } else {

            // event manager is not on the local system

            EvtMgrIP = args[0];

            System.out.println("\n\nAttempting to register on the machine:: " + EvtMgrIP);

            try {
                // Here we create an event manager interface object. This assumes
                // that the event manager is NOT on the local machine
                 heartBeat = new HeartBeat(HBDeviceID,EvtMgrIP);
                em = new EventManagerInterface(EvtMgrIP);
            } catch (Exception e) {
                System.out.println("Error instantiating event manager interface: " + e);

            } // catch

        } // if

        // Here we check to see if registration worked. If em is null then the
        // event manager interface was not properly created.

        if (em != null) {
            System.out.println("Registered with the event manager.");
            heartBeat.start();
            /* Now we create the humidity control status and message panel
             ** We put this panel about 2/3s the way down the terminal, aligned to the left
             ** of the terminal. The status indicators are placed directly under this panel
             */

            float WinPosX = 0.0f; 	//This is the X position of the message window in terms
            //of a percentage of the screen height
            float WinPosY = 0.50f;	//This is the Y position of the message window in terms
            //of a percentage of the screen height

            MessageWindow mw = new MessageWindow("Alarm Controller Status Console", WinPosX, WinPosY);

            // Now we put the indicators directly under the humitity status and control panel

            Indicator alarmInd = new Indicator("Alarm OFF", mw.GetX(), mw.GetY() + mw.Height());
            Indicator systemArmInd = new Indicator("System ARMED", mw.GetX()+(alarmInd.Width()*2), mw.GetY() + mw.Height());
            mw.WriteMessage("Registered with the event manager.");

            try {
                mw.WriteMessage("   Participant id: " + em.GetMyId());
                mw.WriteMessage("   Registration Time: " + em.GetRegistrationTime());

            } // try
            catch (Exception e) {
                System.out.println("Error:: " + e);

            } // catch

            /********************************************************************
             ** Here we start the main simulation loop
             *********************************************************************/
            while (!Done) {
                try {
                    eq = em.GetEventQueue();

                } // try
                catch (Exception e) {
                    mw.WriteMessage("Error getting event queue::" + e);

                } // catch

                // If there are messages in the queue, we read through them.
                // We are looking for EventIDs = 4, this is a request to turn the
                // humidifier or dehumidifier on/off. Note that we get all the messages
                // at once... there is a 2.5 second delay between samples,.. so
                // the assumption is that there should only be a message at most.
                // If there are more, it is the last message that will effect the
                // output of the humidity as it would in reality.

                int qlen = eq.GetSize();

                for (int i = 0; i < qlen; i++) {
                    Evt = eq.GetEvent();
                    if(Evt.GetEventId() == armedEvent)
                    {
                        if (Evt.GetMessage().equalsIgnoreCase("A0")) // arm or disarm system
                        {
                            ArmedState = false;
                            AlarmState = false;
                            mw.WriteMessage("Received DISARM system");

                            // Confirm that the message was recieved and acted on

                            ConfirmMessage(em, "A0");
                         }
                        if (Evt.GetMessage().equalsIgnoreCase("A1")) // arm or disarm system
                        {
                            ArmedState = true;
                            mw.WriteMessage("Received ARMED system");

                            // Confirm that the message was recieved and acted on

                            ConfirmMessage(em, "A1");
                         }
                    }
                    if (Evt.GetEventId() == alarmEvent) {
                      

                        if (Evt.GetMessage().equalsIgnoreCase("W1")) // Turn ON Window Alarm Device
                        {
                            if(ArmedState)
                            {
                                AlarmState = true;
                            }
                            else
                            {
                                AlarmState = false;
                            }
                            mw.WriteMessage("Received Turn ON Window Alarm Device");

                            // Confirm that the message was recieved and acted on

                            ConfirmMessage(em, "W1");

                        } // if

   
                        if (Evt.GetMessage().equalsIgnoreCase("D1")) // Turn on Door Alarm Device
                        {
                            if(ArmedState)
                            {
                                AlarmState = true;
                            }
                            else
                            {
                                AlarmState = false;
                            }
                            mw.WriteMessage("Received Turn on Door Alarm Device");

                            // Confirm that the message was recieved and acted on

                            ConfirmMessage(em, "D1");

                        } // if

                     

                        if (Evt.GetMessage().equalsIgnoreCase("M1")) // Turn on Motion Alarm Device
                        {
                            if(ArmedState)
                            {
                                AlarmState = true;
                            }
                            else
                            {
                                AlarmState = false;
                            }
                            mw.WriteMessage("Received Turn on Motion Alarm Device");

                            // Confirm that the message was recieved and acted on

                            ConfirmMessage(em, "M1");

                        } // if


                    } // if

                    // If the event ID == 99 then this is a signal that the simulation
                    // is to end. At this point, the loop termination flag is set to
                    // true and this process unregisters from the event manager.

                    if (Evt.GetEventId() == 99) {
                        Done = true;

                        try {
                            em.UnRegister();
                            mw.WriteMessage("\n\nUnregistered controller: \n");
                            heartBeat.Close();

                        } // try
                        catch (Exception e) {
                            mw.WriteMessage("Error unregistering: " + e);

                        } // catch

                        mw.WriteMessage("\n\nSimulation Stopped. \n");

                        // Get rid of the indicators. The message panel is left for the
                        // user to exit so they can see the last message posted.
                        alarmInd.dispose();
                        systemArmInd.dispose();
                        
                    } // if

                } // for

                // Update the alarm status

                if (!AlarmState && ArmedState) {
                    // Set to green, Window Alarm is on

                    systemArmInd.SetLampColorAndMessage("System ARMED", 1);
                    alarmInd.SetLampColorAndMessage("Alarm OFF", 0);
                } 
                if(!ArmedState)
                {
                    systemArmInd.SetLampColorAndMessage("System DISARMED", 0);
                    alarmInd.SetLampColorAndMessage("Alarm OFF", 0);
                }
                if(AlarmState && ArmedState)
                {
                    alarmInd.SetLampColorAndMessage("Alarm ON", 3);
                }               
                
                try {
                    Thread.sleep(Delay);

                } // try
                catch (Exception e) {
                    System.out.println("Sleep error:: " + e);
                    heartBeat.Close();

                } // catch

            } // while

        } else {

            System.out.println("Unable to register with the event manager.\n\n");
            heartBeat.Close();
        } // if

    } // main

    /***************************************************************************
     * CONCRETE METHOD:: ConfirmMessage
     * Purpose: This method posts the specified message to the specified event
     * manager. This method assumes an event ID of -4 which indicates a confirma-
     * tion of a command.
     *
     * Arguments: EventManagerInterface ei - this is the eventmanger interface
     *			 where the event will be posted.
     *
     *			 string m - this is the received command.
     *
     * Returns: none
     *
     * Exceptions: None
     *
     ***************************************************************************/
    static private void ConfirmMessage(EventManagerInterface ei, String m) {
        // Here we create the event.

        Event evt = new Event((int) -4, m);

        // Here we send the event to the event manager.

        try {
            ei.SendEvent(evt);

        } // try
        catch (Exception e) {
            System.out.println("Error Confirming Message:: " + e);

        } // catch

    } // PostMessage
}
